﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using Dataglot;

namespace IrishSettings
{
    public enum SettingScope
    {
        None = 0,
        User = 1,
        Application = 2
    }

    public class GenericSetting : GenericSettingStored
    {
        public GenericSetting(GenericSettingSchema validSchema, SettingsApplication app)
        {
            if(validSchema==null)
                throw new ArgumentNullException("validSchema","Schema provided on construction can't be null");
            if(validSchema.Id==0)
            {
                throw new InvalidOperationException("schema needs to have an Id");
            }
            else
            {
                SchemaId = validSchema.Id;
                if (app.Application == null)
                    throw new InvalidOperationException("validSchema.Application==null ... why?");
                if (app.Version == null)
                    throw new InvalidOperationException("validSchema.Application.Version==null ... why?");
                this.Version = app.Version;
            }
            
            Schema = validSchema;
        }

        public GenericSettingSchema Schema { get; private set; }
        //Calculated from SerializedValue
        public object Value { get; set; }
        
        public void Upgrade()
        {
            if(Schema.Id!= SchemaId)
            {
                SchemaId = Schema.Id;
            }
        }
    }

    public class UserSetting : GenericSettingStored
    {
        //Calculated from SerializedValue
        public object Value { get; set; }
        
    }

    public class GenericSettingStored :  ISupportId
    {
        public long Id { get; set; }
        public long SchemaId { get; set; }
        public string SerializedValue { get; set; }
        public string Version { get; set; }
        
        public void ValidateRequirements()
        {
            if (SchemaId == 0)
                throw new InvalidOperationException("Missing required foreign key 'SchemaId'");
            if (string.IsNullOrEmpty(Version))
                throw new InvalidOperationException("Missing required field 'Version'");
        }
    }
    
    public class UserSettingStored : ISupportId
    {
        public long Id { get; set; }
        public long SchemaId { get; set; }
        public string Name { get; set; }
        public string SerializedValue { get; set; }
        public Type ValueType { get; set; }
        public SettingScope Scope { get; set; }
        public string UserName { get; set; }

        public void ValidateRequirements()
        {
            if (SchemaId == 0)
                throw new InvalidOperationException("Missing required foreign key 'SchemaId'");
        }
    }

    public class GenericSettingSchema : GenericSettingSchemaStored
    {
        public GenericSettingSchema()
        {
        }

        
        public Type ValueTypeObject
        {
            get { return Type.GetType(ValueType); }
            set
            {
                if (value == null)
                    ValueType = null;
                else
                    ValueType = value.ToString();
            }
        }
    }

    public class GenericSettingSchemaStored : ISupportId
    {
        public long Id { get; set; }
        public long ApplicationId { get; set; }
        public string Name { get; set; }
        public string DefaultSerializedValue { get; set; }
        public string ValueType { get; set; }
        //public string Culture { get; set; }
        //public string Version { get; set; }
        //public string ApplicationName { get; set; }
        public SettingScope Scope { get; set; }

        //Is user setting
        public bool IsUser { get; set; }

        //Is valid for anonymous
        public bool IsAnonymous { get; set; }

        public void ValidateRequirements()
        {
            if (ApplicationId == 0)
                throw new InvalidOperationException("Missing required foreign key 'ApplicationId'");
        }
    }

    public class SettingsApplication : SettingsApplicationStored
    {
        public SettingsApplication()
        {
            Schema = new SettingsSchema();
        }

        public Version VersionObject
        {
            get
            {
                return new Version(Version);
            }
            set { Version = value.ToString(); }
        }

        public CultureInfo   CultureObject
        {
            get
            {
                return new CultureInfo(Culture);
            }
            set {
                //language code-region code
                Culture = value.ToString();
            }
        }

        /// <summary>
        /// Dictionary of schema items.
        /// </summary>
        public SettingsSchema Schema  { get; set; }
    }

    public class SettingsApplicationStored:ISupportId
    {
        public long Id { get; set; }
        public string Application { get; set; }
        public string Version
        {
            get; 
            set;
        }
        public bool IsActiveVersion { get; set; }
        public string Culture { get; set; }
        public string CurrentVersion { get; set; }
        public string MachineName { get; set; }
        public string DomainName { get; set; }
        public string AppSettingsKey { get; set; }

        public void ValidateRequirements()
        {
            if(string.IsNullOrEmpty(Application))
            {
                throw new InvalidOperationException("Application name is required");
            }
            if (string.IsNullOrEmpty(Version))
            {
                throw new InvalidOperationException("Version name is required");
            }
            if (Culture == null)
                throw new InvalidOperationException("Culture is required to do serializing/deserializing");
        }
    }

}
